#include <iostream>
#include <vector>
#include <string>
#include <unistd.h>
#include "Thread.hpp"
#include "BlockQueue.hpp"
#include "Task.hpp"
using namespace std;
using namespace ThreadModule;

/*
void Consumer(BlockQueue<int> &bq)
{
    while (true)
    {
        int data=0;
        bq.DeQueue(&data);
        cout<<"consumer get data:"<<data<<endl;
    }
}

void Productor(BlockQueue<int> &bq)
{
    int cnt=1;
    while (true)
    {
        bq.EnQueue(cnt);
        cout<<"productor product data:"<<cnt<<endl;
        cnt++;
        sleep(1);
    }
}

void StartCommon(vector<Thread<BlockQueue<int>>> *threads, int threadnum, BlockQueue<int> & bq, func_t<BlockQueue<int>> func)
{
    for (int i = 0; i < threadnum; i++)
    {
        string threadname = "thread -" + to_string(i + 1);
        Thread<BlockQueue<int>> t(func, bq, threadname);
        threads->push_back(t);
        threads->back().Start();
    }
}

void StartConsumer(vector<Thread<BlockQueue<int>>> *threads, int threadnum, BlockQueue<int>& bq) //bq为临时的指针对象,线程类的数据为引用类型
{
    StartCommon(threads, threadnum, bq, Consumer);
}

void StartProductor(vector<Thread<BlockQueue<int>>> *threads, int threadnum, BlockQueue<int>& bq)
{
    StartCommon(threads, threadnum, bq, Productor);
}

void WaitAllThread(vector<Thread<BlockQueue<int>>> &threads)
{
    for (auto &thread : threads)
    {
        thread.Join();
    }
}

int main()
{
    BlockQueue<int> *bq = new BlockQueue<int>(5);
    vector<Thread<BlockQueue<int>>> threads;
    StartConsumer(&threads, 3, *bq);//指针传参时发生值拷贝
    StartProductor(&threads, 4, *bq);

    WaitAllThread(threads);
    return 0;
}
*/

#include <ctime>
using blockqueue_t=BlockQueue<Task>;

void Consumer(blockqueue_t &bq)
{
    while (true)
    {
      //1.从阻塞队列中获取任务
      Task t;
      bq.DeQueue(&t);
      //2.执行任务
      t.Excute();
      cout<<"consumer excute task:"<<t.ToString()<<endl;
    }
}

void Productor(blockqueue_t &bq)
{
    srand((unsigned int)time(nullptr));
    while (true)
    {
        //1.创建任务
        int a=rand()%10+1;//a:1~10
        usleep(1000);
        int b=rand()%20+1;//b:1~20
        Task t(a,b);

        //2.将任务放入阻塞队列中
        bq.EnQueue(t);
        cout<<"productot create task:"<<t.DebugToString()<<endl;
        sleep(2);
    }
}

void StartCommon(vector<Thread<blockqueue_t>> *threads, int threadnum, blockqueue_t & bq, func_t<blockqueue_t> func)
{
    for (int i = 0; i < threadnum; i++)
    {
        string threadname = "thread -" + to_string(i + 1);
        Thread<blockqueue_t> t(func, bq, threadname);
        threads->push_back(t);
        threads->back().Start();
    }
}

void StartConsumer(vector<Thread<blockqueue_t>> *threads, int threadnum, blockqueue_t& bq) //bq为临时的指针对象,线程类的数据为引用类型
{
    StartCommon(threads, threadnum, bq, Consumer);
}

void StartProductor(vector<Thread<blockqueue_t>> *threads, int threadnum, blockqueue_t& bq)
{
    StartCommon(threads, threadnum, bq, Productor);
}

void WaitAllThread(vector<Thread<blockqueue_t>> &threads)
{
    for (auto &thread : threads)
    {
        thread.Join();
    }
}

int main()
{
    blockqueue_t *bq = new blockqueue_t(5);
    vector<Thread<blockqueue_t>> threads;
    StartConsumer(&threads, 1, *bq);//指针传参时发生值拷贝
    StartProductor(&threads, 1, *bq);

    WaitAllThread(threads);
    return 0;
}